import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class XMLHandler {
  private String rawFileName_;
  private String recordId_ = "";
  int limit_;

  public XMLHandler(String fileName, int limit) {
    rawFileName_ = fileName;
    limit_ = limit;
  }
  
  public String getCurrentRecord() {
    return recordId_;
  }
  
  public void updateAuthorTimestamp(AuthorParser ap) throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(rawFileName_);
    doc.getDocumentElement().normalize();

    NodeList records = doc.getElementsByTagName("record");
    for (int ri = 0; ri < records.getLength(); ri++) {
      Element record = (Element) records.item(ri);      
      Element header = (Element) record.getElementsByTagName("header").item(0);
      
      recordId_ = header.getElementsByTagName("identifier").item(0).getFirstChild().getNodeValue();
      
      NodeList setspecs = header.getElementsByTagName("setSpec");
      boolean isvalid = false;
      for (int ssi = 0; ssi < setspecs.getLength(); ++ssi) {
        String cat = setspecs.item(ssi).getChildNodes().item(0).getNodeValue();
        
        if (cat.equals(CoAuthorNetwork.FIELD_)) {
          isvalid = true;
          break;
        }
      }
      
      if (!isvalid) {
        continue;
      }

      Element metadata = (Element) record.getElementsByTagName("metadata").item(0);
      
      String datestamp = metadata.getElementsByTagName("created").item(0).getChildNodes().item(0).getNodeValue();
      
      int date_in_int = Author.DateToInteger(datestamp);
      if (date_in_int > limit_) continue;
      
      Vector<Integer> authorIds = new Vector<Integer>();
      
      NodeList authors = ((Element)metadata.getElementsByTagName("authors").item(0)).getElementsByTagName("author");
      for (int ai = 0; ai < authors.getLength(); ++ai) {
        Element author = (Element) authors.item(ai);
        
        NodeList lastNames = author.getElementsByTagName("keyname");
        
        if (lastNames.getLength() == 0 || lastNames.item(0).getFirstChild() == null) continue;
        String lastName = lastNames.item(0).getFirstChild().getNodeValue();

        NodeList firstNames = author.getElementsByTagName("forenames");
        if (firstNames.getLength() == 0 || firstNames.item(0).getFirstChild() == null) continue;
        if (firstNames.getLength() > 1) throw new Exception("multiple forenames for: " + lastName);
        String firstName = firstNames.item(0).getFirstChild().getNodeValue();
        String name = Author.calculateAuthorName(firstName, lastName);
        
        Integer aid = ap.updateTimestampForAuthor(name, datestamp, recordId_);
        authorIds.add(aid);
      }
      
      ap.addNeighborsForRecord(authorIds, datestamp);
    }    
  }

}
